package com.zilu.digitaltwin.common.util;


import com.zilu.digitaltwin.common.enums.PropertyTypeEnum;
import com.zilu.digitaltwin.common.enums.PunctuationEnum;
import com.zilu.digitaltwin.dao.mapper.InitSqlMapper;
import com.zilu.digitaltwin.dto.dataq.TableColumnDTO;
import com.zilu.digitaltwin.entity.InitSqlBO;
import com.zilu.digitaltwin.service.ModelTableService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 阿里侧-数字孪生底座空间构建应用 初始化sql  纯业务逻辑
 */
@Service
@Slf4j
public class InitSqlUtil {


    @Resource
    ModelTableService service;

    @Resource
    InitSqlMapper initSqlMapper;

    private static ModelTableService modelTableService;

    private static InitSqlMapper initSqlService;


    @PostConstruct
    public void init() {
        modelTableService = service;
        initSqlService = initSqlMapper;
    }


    public static String tableName = "";

    public static List<String> geomMock = new ArrayList<>();

    public static List<String> recordRelTableList = new ArrayList<>();


    public static String metaId = "";

    public static String metaName = "";

    public static List<String> geomNameList = new ArrayList<>();

    public static Map<String, String> parentIdMap = new LinkedHashMap<>(8);

    public static Map<String, String> catalogCodeMap = new LinkedHashMap<>(8);

    public static Map<String, String> entityMap = new LinkedHashMap<>(8);


    public static String getInitCodes(String dataVersion) {

        StringBuilder sb = new StringBuilder();
        List<InitSqlBO> magicList = initSqlService.selectAll(dataVersion);
        if (magicList.size() == 0) {
            return null;
        }
        for (InitSqlBO initSqlBO : magicList) {
            sb.append(initSqlBO.getEntityCode()).append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static void initSql(String codes, String dataVersion) throws Exception {
        List<String> needInitCodes = dealParams(codes);
        StringBuilder result = new StringBuilder();

        List<InitSqlBO> magicList = getAllNeedMagicMap(dataVersion);
        getInitSql(needInitCodes, result, magicList);

        outFile(result.toString());
    }

    private static List<InitSqlBO> getAllNeedMagicMap(String dataVersion) {
        return initSqlService.selectAll(dataVersion);
    }

    private static void getInitSql(List<String> needInitCodes, StringBuilder result, List<InitSqlBO> magicList) throws Exception {
        initCommonSql(needInitCodes, result, magicList);
    }

    /**
     * @param needInitCodes 需要初始化的code 全量
     * @param sb            sb
     * @param specialMagic  需要一个实体绑定两个表的实体的魔法值list 这里的魔法值一定是需要绑定两张表的
     */
    private static void initSpecialSql(List<String> needInitCodes, StringBuilder sb, List<InitSqlBO> specialMagic) {
        //绑定两张表的外键关联信息
        bind2tables(needInitCodes, sb, specialMagic);
        //绑定实体的副表与实体 sm_bind_entity_to_table
        bindRelTable2Entity(sb, specialMagic);
    }

    private static void bindRelTable2Entity(StringBuilder sb, List<InitSqlBO> specialMagic) {
        sb.append(BIND_ENTITY_TO_TABLE);
        int count = 1;

        for (InitSqlBO initSqlBO : specialMagic) {
            count = bindEntityToTable(sb, initSqlBO.getRelTableName(), count, initSqlBO.getEntityCode());
        }

        sb.append(PunctuationEnum.Semicolon.getValue());
        format(sb);
    }

    private static void bind2tables(List<String> needInitCodes, StringBuilder sb, List<InitSqlBO> specialMagic) {
        List<InitSqlBO> needInitSpecialList = specialMagic.stream().filter(x -> !needInitCodes.contains(x)).collect(Collectors.toList());
        if (needInitSpecialList.size() == 0) {
            return;
        }
        sb.append(ENTITY_TO_MANY);
        Map<String, Object> tmpMap = new LinkedHashMap<>(4);
        int count = 1;
        for (InitSqlBO magicInfo : needInitSpecialList) {
            String relation = getBindRelation(magicInfo);
            tmpMap.put("entityCode", magicInfo.getEntityCode());
            tmpMap.put("relation", relation);
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(ENTITY_TO_MANY_SQL, tmpMap);
            if (count++ != 1) {
                sb.append(PunctuationEnum.Colon.getValue()).append(result);
            } else {
                sb.append(result);
            }
        }
        sb.append(PunctuationEnum.Semicolon.getValue()).append('\n');
        format(sb);
    }

    private static String getBindRelation(InitSqlBO magicInfo) {
        String pkTable = magicInfo.getTableName();
        String pkId = magicInfo.getMetaId();
        String relTable = magicInfo.getRelTableName();
        String relPkId = magicInfo.getRelPkId();
        return pkTable + "." + pkId + ":" + relTable + "." + relPkId;
    }

    private static void initCommonSql(List<String> needInitCodes, StringBuilder sb, List<InitSqlBO> magicList) throws Exception {
        List<InitSqlBO> newMagicList = new ArrayList<>();
        Map<String, InitSqlBO> code2MagicMap = new LinkedHashMap<>(16);
        //过滤出需要生成sql的实体
        for (InitSqlBO magicBo : magicList) {
            String entityCode = magicBo.getEntityCode();
            for (String needInitCode : needInitCodes) {
                if (entityCode.equals(needInitCode)) {
                    newMagicList.add(magicBo);
                    code2MagicMap.put(needInitCode, magicBo);
                }
            }
        }
        magicList = newMagicList;
        //key为表名  value是表名对应的数据
        Map<String, List<InitSqlBO>> mapGroup = magicList.stream().collect(Collectors.groupingBy(InitSqlBO::getTableName));
        //提前插入需要关联的表
        for (InitSqlBO bo : magicList) {
            if (StringUtils.isNotBlank(bo.getRelTableName())) {
                createAndSelectTableId(sb, bo.getRelTableName());
            }
        }
        for (Map.Entry<String, List<InitSqlBO>> entry : mapGroup.entrySet()) {
            initData(entry);
            //核心逻辑  生成初始sql
            StringBuilder initSql = getInitSql(tableName, entityMap, entry.getValue(), code2MagicMap);
            sb.append(initSql);
        }

        List<InitSqlBO> specialMagic = magicList.stream().filter(x -> StringUtils.isNotBlank(x.getRelTableName())).collect(Collectors.toList());
        initSpecialSql(needInitCodes, sb, specialMagic);
    }


    private static List<String> dealParams(String codes) {
        codes = codes.replaceAll(" ", "");
        List<String> needInitCodes = Arrays.asList(codes.split(PunctuationEnum.Colon.getValue()));
        needInitCodes = needInitCodes.stream().distinct().collect(Collectors.toList());
        return needInitCodes;
    }

    private static void initData(Map.Entry<String, List<InitSqlBO>> entry) {
        entityMap.clear();
        geomNameList.clear();
        tableName = entry.getKey();
        InitSqlBO bo = entry.getValue().get(0);
        metaId = bo.getMetaId();
        metaName = bo.getMetaName();
        List<InitSqlBO> magicList = entry.getValue();
        for (InitSqlBO magic : magicList) {
            String entityCode = magic.getEntityCode();
            entityMap.put(entityCode, magic.getEntityName());
            parentIdMap.put(entityCode, magic.getParentId());
            catalogCodeMap.put(entityCode, magic.getBizCatalogCode());
        }


    }


    /**
     * 获取初始化sql
     *
     * @param tableName     表名   不可为空
     * @param entityMap     实体的名称+唯一code  例如 元路段/rid
     * @param code2MagicMap
     * @return 初始化sql
     */
    private static StringBuilder getInitSql(String tableName, Map<String, String> entityMap,
                                            List<InitSqlBO> magicList, Map<String, InitSqlBO> code2MagicMap) throws Exception {
        StringBuilder sb = new StringBuilder();
        //创建实体sql
        getEntitySql(sb, tableName, entityMap, code2MagicMap);
        //更新实体catalog_id
        //更新实体parent_id
        //数据源id查询
        updateOrSelectId(sb);
        //实体id查询
        selectEntityId(entityMap, sb);
        //新建物理表
        //查询物理表id
        createAndSelectTableId(sb, tableName);
        //新建物理表字段
        createTableColumns(sb, tableName, entityMap, code2MagicMap);
        //新建实体属性
        createEntityProperties(sb, tableName, entityMap, code2MagicMap);
        //新建实体和关系过滤器
        createEntityFilter(sb, tableName, entityMap, code2MagicMap);
        //新建实体和物理表绑定关系
        bindEntityToTable(sb, tableName, entityMap);
        //把实体挂载到业务目录树上
        bindEntity2BizTree(sb, entityMap, magicList, code2MagicMap);
        //配置默认实体编码规则
        codeRule(sb);
        return sb;
    }

    private static void createEntityFilter(StringBuilder sb, String tableName, Map<String, String> entityMap, Map<String, InitSqlBO> code2MagicMap) {

        Map<String, Object> tmpMap = new LinkedHashMap<>(16);
        int count = 1;
        int geomCount = 1;
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            InitSqlBO filterInfo = code2MagicMap.get(entry.getKey());
            if (StringUtils.isBlank(filterInfo.getFilterColumn())) {
                continue;
            }
            String[] filterColumns = filterInfo.getFilterColumn().split(",");
            String[] filterConditions = filterInfo.getFilterCondition().split(",");
            String[] filterValues = filterInfo.getFilterValue().split("#");
            if (filterColumns.length == 0) {
                continue;
            }
            if (geomCount++ == 1) {
                sb.append(ENTITY_TO_FILTER);
            }
            for (int i = 0; i < filterColumns.length; i++) {
                tmpMap.put("entityCode", entry.getKey());
                tmpMap.put("tableName", tableName);
                tmpMap.put("filterColumn", filterColumns[i]);
                tmpMap.put("filterCondition", filterConditions[i]);
                tmpMap.put("filterValue", filterValues[i]);

                dealMap(tmpMap);
                String result = PlaceholderUtils.replaceWithMap(ENTITY_TO_FILTER_SQL, tmpMap);
                if (count++ != 1) {
                    sb.append(PunctuationEnum.Colon.getValue()).append(result);
                } else {
                    sb.append(result);
                }

            }


        }
        sb.append(PunctuationEnum.Semicolon.getValue()).append('\n');
        format(sb);

    }

    private static void bindEntity2BizTree(StringBuilder sb, Map<String, String> entityMap, List<InitSqlBO> magicList, Map<String, InitSqlBO> code2MagicMap) {
        //从全量的实体中过滤出catalogCode不为空的（不需要挂载到业务目录树上的）
        Map<String, String> newMap = new LinkedHashMap<>(8);

        for (String entityCode : entityMap.keySet()) {
            for (InitSqlBO magicBo : magicList) {
                if (!magicBo.getEntityCode().equals(entityCode)) {
                    continue;
                }
                if (!StringUtils.isBlank(magicBo.getBizCatalogCode())) {
                    newMap.put(entityCode, entityMap.get(entityCode));
                }
            }
        }

        if (newMap.size() == 0) {
            return;
        }

        Map<String, Object> tmpMap = new LinkedHashMap<>(16);


        for (Map.Entry<String, String> entry : newMap.entrySet()) {
            InitSqlBO initSqlBO = code2MagicMap.get(entry.getKey());
            tmpMap.put("catalogCode", initSqlBO.getBizCatalogCode());
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(ENTITY_TO_BIZ_TREE_CODE, tmpMap);
            sb.append(result);
        }

        dealMap(tmpMap);
        sb.append(PlaceholderUtils.replaceWithMap(ENTITY_TO_BIZ_TREE, tmpMap));
        tmpMap.clear();
        int count = 1;
        int orderNo = 1;
        for (Map.Entry<String, String> entry : newMap.entrySet()) {
            tmpMap.put("catalogCode", catalogCodeMap.get(entry.getKey()));
            tmpMap.put("orderNo", orderNo++);
            tmpMap.put("entityCode", entry.getKey());
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(ENTITY_TO_BIZ_TREE_SQL, tmpMap);
            if (count++ != 1) {
                sb.append(PunctuationEnum.Colon.getValue()).append(result);
            } else {
                sb.append(result);
            }
        }

        sb.append(PunctuationEnum.Semicolon.getValue());
        format(sb);
    }

    private static void codeRule(StringBuilder sb) {
        sb.append(CODE_RULE);
        Map<String, Object> tmpMap = new LinkedHashMap<>(16);
        int count = 1;
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            tmpMap.put("entityCode", entry.getKey());
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(CODE_RULE_SQL, tmpMap);
            if (count++ != 1) {
                sb.append(PunctuationEnum.Colon.getValue()).append(result);
            } else {
                sb.append(result);
            }
        }

        sb.append(PunctuationEnum.Semicolon.getValue());
        format(sb);
    }

    /**
     * 以表名group
     *
     * @param sb        sb
     * @param tableName group的分组
     * @param entityMap 对应实体map
     */
    private static void bindEntityToTable(StringBuilder sb, String tableName, Map<String, String> entityMap) {
        sb.append(BIND_ENTITY_TO_TABLE);

        int count = 1;
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            count = bindEntityToTable(sb, tableName, count, entry.getKey());
        }

        sb.append(PunctuationEnum.Semicolon.getValue());
        format(sb);
    }

    private static int bindEntityToTable(StringBuilder sb, String tableName, int count, String entityCode) {
        Map<String, Object> tmpMap = new LinkedHashMap<>(2);
        tmpMap.put("entityCode", entityCode);
        tmpMap.put("tableName", tableName);
        dealMap(tmpMap);
        String result = PlaceholderUtils.replaceWithMap(BIND_ENTITY_TO_TABLE_SQL, tmpMap);
        if (count++ != 1) {
            sb.append(PunctuationEnum.Colon.getValue()).append(result);
        } else {
            sb.append(result);
        }
        return count;
    }

    private static void createEntityProperties(StringBuilder sb, String tableName, Map<String, String> entityMap, Map<String, InitSqlBO> code2MagicMap) {
        creatEntityProperties(sb, tableName, entityMap, code2MagicMap);
        format(sb);
    }

    private static void creatEntityProperties(StringBuilder sb, String tableName, Map<String, String> entityMap, Map<String, InitSqlBO> code2MagicMap) {

        sb.append(SM_ENTITY_PROPERTIES);
        int count = 1;
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            InitSqlBO initSqlBO = code2MagicMap.get(entry.getKey());
            String entityCode = entry.getKey();
            creatEntityProperty(sb, tableName, initSqlBO, entityCode);
            if (count++ != entityMap.size()) {
                sb.append(PunctuationEnum.Colon.getValue()).append("\n");
            }
        }
        sb.append(PunctuationEnum.Semicolon.getValue()).append("\n");
        format(sb);
    }

    private static void creatEntityProperty(StringBuilder sb, String tableName, InitSqlBO magic, String entityCode) {
        geomMock.clear();
        geomNameList.clear();
        geomNameList.addAll(Arrays.asList(magic.getGeomName().split(",")));
        Map<String, Object> tmpMap = new LinkedHashMap<>(16);
//        List<TableColumnDTO> tableColumns = getColumns(magic);
        Map<String, List<TableColumnDTO>> listMap = getColumns(magic);
        //用来记录绑定两个表的时候去重用
        List<String> tmpList = new ArrayList<>();
        String tmpTableName = null;
        int orderNo = 1;
        int count = 1;
        for (Map.Entry<String, List<TableColumnDTO>> entry : listMap.entrySet()) {
            tmpTableName = entry.getKey();
            List<TableColumnDTO> columns = entry.getValue();
            for (TableColumnDTO tableColumn : columns) {
                String name = tableColumn.getName();
                if (tmpList.contains(name)) {
                    continue;
                }
                tmpList.add(name);
                tmpMap.put("entityCode", entityCode);
                tmpMap.put("name", name);
                tmpMap.put("code", name);
                tmpMap.put("orderNo", orderNo++);
                tmpMap.put("tableName", tmpTableName);
                tmpMap.put("columnName", name);

                tmpMap.put("propertyType", PropertyTypeEnum.getSmCode(tableColumn.getType()));

                if (tableColumn.getComment() == null) {
                    tmpMap.put("description", "");
                } else {
                    tmpMap.put("description", tableColumn.getComment());
                }

                if (metaId.equals(tableColumn.getName())) {
                    tmpMap.put("metaType", "ID");
                } else if (metaName.equals(tableColumn.getName())) {
                    tmpMap.put("metaType", "NAME");
                } else {
                    tmpMap.put("metaType", "null");
                }

                String metaName = magic.getMetaId();
                if (name.equals(metaName)) {
                    tmpMap.put("isPk", 1);
                } else {
                    tmpMap.put("isPk", 0);
                }

                if (geomNameList.size() != 0 && geomNameList.contains(tableColumn.getName())) {
                    for (String geomName : geomNameList) {
                        if (geomName.equals(tableColumn.getName())) {
                            tmpMap.put("isGeometry", 1);
                            tmpMap.put("geometryType", getGeomType(magic));
                        }
                    }
                } else {
                    tmpMap.put("isGeometry", 0);
                    tmpMap.put("geometryType", "null");
                }
                dealMap(tmpMap);
                String result = PlaceholderUtils.replaceWithMap(SM_ENTITY_PROPERTIES_SQL, tmpMap);
                if (count != 1) {
                    sb.append(PunctuationEnum.Colon.getValue()).append(result);
                } else {
                    sb.append(result);
                }
                count++;
            }
        }

        sb.append("\n");
    }

    private static Object getGeomType(InitSqlBO initSqlBO) {
        String geomName = initSqlBO.getGeomName();
        String[] geomTypeList = geomName.split(",");
        if (geomTypeList.length == 1) {
            return "GEOMETRY_" + initSqlBO.getEntityType().toUpperCase();
        }

        String point = "point";
        String line = "line";
        String polygon = "polygon";

        if (geomMock.size() == 0) {
            geomMock.add(initSqlBO.getEntityType());
            return "GEOMETRY_" + initSqlBO.getEntityType().toUpperCase();
        }
        if (!geomMock.contains(point)) {
            geomMock.add(point);
            return "GEOMETRY_" + line.toUpperCase();
        } else if (!geomMock.contains(line)) {
            geomMock.add(line);
            return "GEOMETRY_" + polygon.toUpperCase();
        } else if (!geomMock.contains(polygon)) {
            geomMock.add(polygon);
            return "GEOMETRY_" + point.toUpperCase();
        }
        return "";

    }

    private static void createTableColumns(StringBuilder sb, String tableName, Map<String, String> entityMap, Map<String, InitSqlBO> code2MagicMap) {

        List<String> recordList = new ArrayList<>();
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            String entityCode = entry.getKey();

            InitSqlBO initSqlBO = code2MagicMap.get(entityCode);

            if (!recordList.contains(initSqlBO.getTableName())) {
                recordList.add(initSqlBO.getTableName());
                createTableColumns(sb, tableName, initSqlBO);
            }
            String relTableName = initSqlBO.getRelTableName();
            if (StringUtils.isNotBlank(relTableName) && !recordList.contains(relTableName)) {
                createTableColumns(sb, relTableName, initSqlBO);
            }
        }

    }

    private static void createTableColumns(StringBuilder sb, String tableName, InitSqlBO value) {
        List<TableColumnDTO> tableColumns = getColumns(tableName);
        sb.append(SM_TABLE_COLUMN);
        Map<String, Object> tmpMap = new LinkedHashMap<>(16);

        int count = 1;
        for (TableColumnDTO tableColumn : tableColumns) {
            tmpMap.put("tableName", tableName);
            tmpMap.put("name", tableColumn.getName());
            tmpMap.put("type", tableColumn.getType());
            tmpMap.put("isNullable", isNullable(tableColumn.getNotNull()));
            if (tableColumn.getComment() == null) {
                tmpMap.put("comment", "");
            } else {
                tmpMap.put("comment", tableColumn.getComment());
            }


            if (tableColumn.getColumnLength() == null) {
                tmpMap.put("columnLength", "null");
            } else {
                tmpMap.put("columnLength", tableColumn.getColumnLength());
            }

            if (tableColumn.getName().equals(value.getMetaId())) {
                tmpMap.put("isPk", 1);
            } else {
                tmpMap.put("isPk", 0);
            }

            tmpMap.put("isPartitioned", isNullable(tableColumn.getPartition()));
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(SM_TABLE_COLUMN_SQL, tmpMap);
            if (count != 1) {
                sb.append(PunctuationEnum.Colon.getValue()).append(result);
            } else {
                sb.append(result);
            }
            count++;

        }
        sb.append(PunctuationEnum.Semicolon.getValue());
        format(sb);
    }

    private static Integer isNullable(Boolean notNull) {
        return notNull ? 1 : 0;
    }

    private static List<TableColumnDTO> getColumns(String tableName) {
        return modelTableService.listColumnByCode(tableName);
    }

    private static Map<String, List<TableColumnDTO>> getColumns(InitSqlBO magic) {
        List<TableColumnDTO> pkTableColumns = modelTableService.listColumnByCode(tableName);
        String relTableName = magic.getRelTableName();
        Map<String, List<TableColumnDTO>> bindColumnsMap = new LinkedHashMap<>();
        bindColumnsMap.put(tableName, pkTableColumns);
        if (StringUtils.isNotBlank(relTableName)) {
            //如果实体要关联多表  需要字段去重 否则孪生会报错
            List<TableColumnDTO> relTableColumns = modelTableService.listColumnByCode(relTableName);
            bindColumnsMap.put(relTableName, relTableColumns);
        }

        return bindColumnsMap;
    }


    private static void createAndSelectTableId(StringBuilder sb, String tableName) {
        Map<String, Object> tmpMap = new LinkedHashMap<>(2);
        tmpMap.put("tableName", tableName);
        dealMap(tmpMap);
        String createSql = PlaceholderUtils.replaceWithMap(CREATE_TABLE, tmpMap);
        sb.append(createSql);
        String selectSql = PlaceholderUtils.replaceWithMap(GET_TABLE_ID, tmpMap);
        sb.append(selectSql);
        format(sb);
    }

    private static void selectEntityId(Map<String, String> entityMap, StringBuilder sb) {
        Map<String, Object> tmpMap = new LinkedHashMap<>(2);
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            tmpMap.put("code", entry.getKey());
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(GET_ENTITY_ID, tmpMap);
            sb.append(result);
        }

        format(sb);
    }

    private static void updateOrSelectId(StringBuilder sb) {
        sb.append(UPDATE_CATALOG_ID);
        format(sb);
        sb.append(UPDATE_PARENT_ID);
        format(sb);
        sb.append(DATA_SOURCE_ID);
        format(sb);
    }

    private static void getEntitySql(StringBuilder sb, String tableName, Map<String, String> entityMap, Map<String, InitSqlBO> code2MagicMap) {
        sb.append(SM_ENTITY);

        Map<String, Object> tmpMap = new LinkedHashMap<>(8);
        int count = 1;
        for (Map.Entry<String, String> entry : entityMap.entrySet()) {
            String entityCode = entry.getKey();
            tmpMap.put("code", entityCode);
            tmpMap.put("name", entry.getValue());
            tmpMap.put("tableName", tableName);
            tmpMap.put("pkId", metaId);
            tmpMap.put("entityType", code2MagicMap.get(entityCode).getEntityType());
            tmpMap.put("parentId", parentIdMap.get(entry.getKey()));
            dealMap(tmpMap);
            String result = PlaceholderUtils.replaceWithMap(SM_ENTITY_SQL, tmpMap);
            if (count++ == 1) {
                sb.append(result);
            } else {
                sb.append(PunctuationEnum.Colon.getValue()).append(result);
            }

        }
        sb.append(PunctuationEnum.Semicolon.getValue());

        format(sb);
    }

    private static void dealMap(Map<String, Object> tmpMap) {
        for (Map.Entry<String, Object> entry : tmpMap.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof String && !"null".equals(value)) {
                String singleQuotesValue = PunctuationEnum.SINGLE_QUOTES.getValue();
                String result = singleQuotesValue + value + singleQuotesValue;
                tmpMap.put(entry.getKey(), result);
            }
        }
    }

    private static void format(StringBuilder sb) {
        sb.append("\n\n");
    }


    /**
     * 根据内容输出到指定位置  默认 “D:\1.txt“  需要修改的话到FileUtils中自行修改
     *
     * @param content 需要输出的内容
     */
    public static void outFile(String content) {
        FileUtils.outFile(content);
    }


    /*
     * -- 创建实体
     */
    public static final String SM_ENTITY = "insert into sm_entity (project_id, name, order_no, code, pk_table, pk_column, state, description,\n" +
            "                       entity_type, catalog_id, catalog_general_id, parent_general_id,\n" +
            "                       inherit_rule_configuration, is_inherit, is_visible, is_system)\n" +
            "values \n";

    /*
     * -- 创建实体
     */
    public static final String SM_ENTITY_SQL = " (@project_id, ${name}, 1, ${code}, ${tableName}, ${pkId}, 1, ${name}, ${entityType}, 0, ${parentId}, '0', null, 0, 1, 0)\n";

    /*
     * -- 更新实体catalog_id
     */
    public static final String UPDATE_CATALOG_ID = "update sm_entity as entity left join sm_entity_catalog as catalog on entity.catalog_general_id = catalog.general_id\n" +
            "set entity.catalog_id=catalog.id\n" +
            "where entity.project_id = @project_id and catalog.project_id = @project_id;";

    /*
     * -- 更新实体parent_id
     */
    public static final String UPDATE_PARENT_ID = "update sm_entity as entity left join sm_entity as parent on entity.parent_general_id = parent.code\n" +
            "set entity.parent_id=parent.id\n" +
            "where entity.project_id = @project_id and parent.project_id = @project_id;";


    /*
     *  -- 实体id查询
     */
    public static final String GET_ENTITY_ID = "select @${code} := id from sm_entity where project_id = @project_id and code = ${code};\n";

    /*
     *  -- 数据源id查询
     */
    public static final String DATA_SOURCE_ID = "select @cts_adb_pre := id from sm_datasource where project_id = @project_id and code = 'cts_adb_pre';\n";

    /*
     *  -- 新建物理表
     */
    public static final String CREATE_TABLE = "insert into sm_table_info (project_id, name, datasource_id, comment, logic_delete_configuration)\n" +
            "values (@project_id, ${tableName}, @cts_adb_pre, null, null);\n";
    /*
     *  -- 查询物理表id
     */
    public static final String GET_TABLE_ID = "select @${tableName} := id from sm_table_info where datasource_id = @cts_adb_pre and name = ${tableName} and project_id = @project_id;\n";

    /*
     *  --  新建物理表字段
     */
    public static final String SM_TABLE_COLUMN = "insert into sm_table_column (project_id, table_id, name, type, length, is_nullable, is_pk, is_partitioned,is_auto_increment, comment)\n" +
            "values\n";

    /*
     *  --  新建物理表字段
     */
    public static final String SM_TABLE_COLUMN_SQL = " (@project_id, @${tableName}, ${name}, ${type}, ${columnLength}, ${isNullable}, ${isPk}, ${isPartitioned},  0 , ${comment})\n";

    /*
     *  --  新建实体属性
     */
    public static final String SM_ENTITY_PROPERTIES = "insert into sm_entity_property (project_id, entity_id, entity_relation_id, name, code, description, order_no, table_name,\n" +
            "                                column_name, property_type, geometry_type, coordinate_system, group_no, meta_type,\n" +
            "                                is_geometry, is_queryable, is_nullable, is_fixed, is_editable, is_pk)\n" +
            "values\n";

    /*
     *  --  新建实体属性
     */
    public static final String SM_ENTITY_PROPERTIES_SQL = " (@project_id, @${entityCode}, null, ${name}, ${code}, ${description}, ${orderNo}, ${tableName}, ${columnName}, ${propertyType}, ${geometryType}, null, null, ${metaType}, ${isGeometry}, 1, 1, 0, 1, ${isPk})\n";

    /*
     *  --  新建实体和关系过滤器
     */

    /*
     *  --  新建实体和物理表绑定关系
     */
    public static final String BIND_ENTITY_TO_TABLE = "insert into sm_bind_entity_to_table (project_id, entity_id, table_id)\n" +
            "values\n";

    /*
     *  --  新建实体和物理表绑定关系
     */
    public static final String BIND_ENTITY_TO_TABLE_SQL = " (@project_id, @${entityCode}, @${tableName})\n";

    /*
     *  --  配置默认实体编码规则
     */
    public static final String CODE_RULE = "insert into sm_entity_code_rule \n" +
            "(project_id, entity_id,version,split_code,sequence_code_figure,is_manage_code_empty,is_space_code_empty,is_time_code_empty)\n" +
            "values\n";

    /*
     *  --  配置默认实体编码规则
     */
    public static final String CODE_RULE_SQL = " (@project_id,@${entityCode},'1.0.0','X',3,0,0,0)\n";


    /*
     *  --  绑定实体到业务目录树上
     */
    public static final String ENTITY_TO_BIZ_TREE = "insert into sm_biz_catalog_entity (project_id, catalog_id, entity_id, order_no)\n" +
            "values \n";

    /*
     *  --  查询所有的业务目录id
     */
    public static final String ENTITY_TO_BIZ_TREE_CODE = "select @${catalogCode} := id from sm_biz_catalog where project_id = @project_id and code = ${catalogCode};\n";

    /*
     *  --  绑定实体到业务目录树上
     */
    public static final String ENTITY_TO_BIZ_TREE_SQL = " (@project_id, @${catalogCode}, @${entityCode}, ${orderNo})\n";

    /*
     *  --  新建实体和关系过滤器
     */
    public static final String ENTITY_TO_FILTER = "insert into sm_bind_filter (project_id, bind_target_type, bind_target_id, filter_table_name, filter_column_name,\n" +
            "                            filter_rule, filter_value)\n" +
            "values \n";

    /*
     *  --  新建实体和关系过滤器
     */
    public static final String ENTITY_TO_FILTER_SQL = " (@project_id, 'ENTITY_TO_TABLE', @${entityCode}, ${tableName}, ${filterColumn}, ${filterCondition}, ${filterValue})\n";

    /*
     *  --  单实体多表关联关系
     */
    public static final String ENTITY_TO_MANY = "insert into sm_entity_table_relation (project_id, entity_id, column_pair, rel_map)\n" +
            "values \n";

    /*
     *  --  单实体多表关联关系
     */
    public static final String ENTITY_TO_MANY_SQL = " (@project_id, @${entityCode}, ${relation}, 'ONE_TO_ONE')\n";

}
